home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-13 / joe014.zip / JOE014.TAZ / JOE014.tar / asynchpux.c < prev    next >
C/C++ Source or Header  |  1992-01-23  |  5KB  |  285 lines

  1. /* Terminal interface for HPUX
  2.    Copyright (C) 1991 Joseph H. Allen
  3.  
  4. This file is part of JOE (Joe's Own Editor)
  5.  
  6. JOE is free software; you can redistribute it and/or modify it under the terms
  7. of the GNU General Public License as published by the Free Software
  8. Foundation; either version 1, or (at your option) any later version. 
  9.  
  10. JOE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE.  See the GNU General Public License for more details.  
  13.  
  14. You should have received a copy of the GNU General Public License
  15. along with JOE; see the file COPYING.  If not, write to
  16. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. #include <stdio.h>
  19. #include <signal.h>
  20. #include <fcntl.h>
  21. #include <time.h>
  22. #include <sys/param.h>
  23. #include <termio.h>
  24. #include "async.h"
  25.  
  26. #define DIVISOR 12000000
  27. #define TIMES 2
  28.  
  29. static struct termio oldterm;
  30.  
  31. static unsigned char *obuf=0;
  32. static unsigned obufp=0;
  33. static unsigned obufsiz;
  34. static unsigned long ccc;
  35.  
  36. static unsigned speeds[]=
  37. {
  38. B50,50,B75,75,B110,110,B134,134,B150,150,B200,200,B300,300,B600,600,B1200,1200,
  39. B1800,1800,B2400,2400,B4800,4800,B9600,9600,EXTA,19200,EXTB,38400
  40. };
  41.  
  42. void tsignal();
  43.  
  44. sigjoe()
  45. {
  46. signal(SIGHUP,tsignal);
  47. signal(SIGTERM,tsignal);
  48. signal(SIGINT,SIG_IGN);
  49. signal(SIGPIPE,SIG_IGN);
  50. signal(SIGQUIT,SIG_IGN);
  51. }
  52.  
  53. signorm()
  54. {
  55. signal(SIGHUP,SIG_DFL);
  56. signal(SIGTERM,SIG_DFL);
  57. signal(SIGINT,SIG_DFL);
  58. signal(SIGPIPE,SIG_DFL);
  59. signal(SIGQUIT,SIG_DFL);
  60. }
  61.  
  62. aopen()
  63. {
  64. int x;
  65. struct termio newterm;
  66. fflush(stdout);
  67. ioctl(fileno(stdin),TCGETA,&oldterm);
  68. newterm=oldterm;
  69. newterm.c_lflag=0;
  70. newterm.c_iflag&=~(ICRNL|IGNCR|INLCR);
  71. newterm.c_oflag=0;
  72. newterm.c_cc[VMIN]=1;
  73. newterm.c_cc[VTIME]=0;
  74. ioctl(fileno(stdin),TCSETAW,&newterm);
  75. ccc=0;
  76. for(x=0;x!=30;x+=2)
  77.  if((newterm.c_cflag&CBAUD)==speeds[x])
  78.   {
  79.   ccc=DIVISOR/speeds[x+1];
  80.   break;
  81.   }
  82. if(obuf) free(obuf);
  83. if(!(TIMES*ccc)) obufsiz=4096;
  84. else
  85.  {
  86.  obufsiz=1000000/(TIMES*ccc);
  87.  if(obufsiz>4096) obufsiz=4096;
  88.  }
  89. if(!obufsiz) obufsiz=1;
  90. obuf=(unsigned char *)malloc(obufsiz);
  91. }
  92.  
  93. aclose()
  94. {
  95. aflush();
  96. ioctl(fileno(stdin),TCSETAW,&oldterm);
  97. }
  98.  
  99. int have=0;
  100. static unsigned char havec;
  101. static int yep;
  102.  
  103. static dosig()
  104. {
  105. yep=1;
  106. }
  107.  
  108. aflush()
  109. {
  110. if(obufp)
  111.  {
  112.  struct itimerval a,b;
  113.  unsigned long usec=obufp*ccc;
  114.  if(usec>=500000/10 /* HZ */)
  115.   {
  116.   a.it_value.tv_sec=usec/1000000;
  117.   a.it_value.tv_usec=usec%1000000;
  118.   a.it_interval.tv_usec=0;
  119.   a.it_interval.tv_sec=0;
  120.   signal(SIGALRM,dosig);
  121.   yep=0;
  122.   sigsetmask(sigmask(SIGALRM));
  123.   setitimer(ITIMER_REAL,&a,&b);
  124.   write(fileno(stdout),obuf,obufp);
  125.   while(!yep) sigpause(0);
  126.   signal(SIGALRM,SIG_DFL);
  127.   }
  128.  else write(fileno(stdout),obuf,obufp);
  129.  obufp=0;
  130.  }
  131. if(!have)
  132.  {
  133.  fcntl(fileno(stdin),F_SETFL,O_NDELAY);
  134.  if(read(fileno(stdin),&havec,1)==1) have=1;
  135.  fcntl(fileno(stdin),F_SETFL,0);
  136.  }
  137. }
  138.  
  139. unsigned char *take=0;
  140.  
  141. anext()
  142. {
  143. if(take)
  144.  if(*take)
  145.   {
  146.   int c;
  147.   if(*take!='\\') return *take++;
  148.   ++take;
  149.   if(!*take) return '\\';
  150.   else if(*take=='r') c='\r';
  151.   else if(*take=='b') c=8;
  152.   else if(*take=='n') c=10;
  153.   else if(*take=='f') c=12;
  154.   else if(*take=='a') c=7;
  155.   else if(*take=='\"') c='\"';
  156.   else if(*take>='0' && *take<='7')
  157.         {
  158.         c= *take++-'0';
  159.         if(*take>='0' && *take<='7')
  160.          {
  161.          c=c*8+*take++-'0';
  162.          if(*take>='0' && *take<='7') c=c*8+*take++-'0';
  163.          }
  164.         --take;
  165.         }
  166.   else c= *take;
  167.   ++take;
  168.   return c;
  169.   }
  170.  else take=0;
  171. aflush();
  172. if(have) have=0;
  173. else if(read(fileno(stdin),&havec,1)<1) tsignal(0);
  174. if(record) macroadd(havec);
  175. return havec;
  176. }
  177.  
  178. eputc(c)
  179. unsigned char c;
  180. {
  181. obuf[obufp++]=c;
  182. if(obufp==obufsiz) aflush();
  183. }
  184.  
  185. eputs(s)
  186. char *s;
  187. {
  188. while(*s)
  189.  {
  190.  obuf[obufp++]= *(s++);
  191.  if(obufp==obufsiz) aflush();
  192.  }
  193. }
  194.  
  195. getsize()
  196. {
  197. #ifdef TIOCGSIZE
  198. struct ttysize getit;
  199. #else
  200. #ifdef TIOCGWINSZ
  201. struct winsize getit;
  202. #else
  203. char *p;
  204. #endif
  205. #endif
  206. #ifdef TIOCGSIZE
  207. if(ioctl(fileno(stdout),TIOCGSIZE,&getit)!= -1)
  208.  {
  209.  if(getit.ts_lines>=3) height=getit.ts_lines;
  210.  if(getit.ts_cols>=2) width=getit.ts_cols;
  211.  }
  212. #else
  213. #ifdef TIOCGWINSZ
  214. if(ioctl(fileno(stdout),TIOCGWINSZ,&getit)!= -1)
  215.  {
  216.  if(getit.ws_row>=3) height=getit.ws_row;
  217.  if(getit.ws_col>=2) width=getit.ws_col;
  218.  }
  219. #else
  220. if(p=getenv("ROWS")) sscanf(p,"%d",&height);
  221. if(p=getenv("COLS")) sscanf(p,"%d",&width);
  222. if(height<3) height=24;
  223. if(width<2) width=80;
  224. #endif
  225. #endif
  226. }
  227.  
  228. termtype()
  229. {
  230. unsigned char entry[1024];
  231. unsigned char area[1024];
  232. unsigned char *foo=area;
  233. unsigned char *x=(unsigned char *)getenv("TERM");
  234. if(!x) goto down;
  235. if(tgetent(entry,x)!=1) goto down;
  236. height=tgetnum("li");
  237. if(height<3) height=24;
  238. width=tgetnum("co");
  239. if(width<2) width=80;
  240. if(!tgetstr("cs",&foo)) scroll=0;
  241. down:
  242. getsize();
  243. }
  244.  
  245. shell()
  246. {
  247. int x;
  248. char *s=(char *)getenv("SHELL");
  249. if(!s)
  250.  {
  251.  puts("\nSHELL variable not set");
  252.  return;
  253.  }
  254. eputs("\nYou are at the command shell.  Type 'exit' to continue editing\r\n");
  255. aclose();
  256. if(x=fork())
  257.  {
  258.  if(x!= -1) wait(0);
  259.  }
  260. else
  261.  {
  262.  signorm();
  263.  execl(s,s,0);
  264.  _exit(0);
  265.  }
  266. aopen();
  267. }
  268.  
  269. susp()
  270. {
  271. #ifdef SIGCONT
  272. eputs("\nThe editor has been suspended.  Type 'fg' to continue editing\r\n");
  273. yep=0;
  274. aclose();
  275. signal(SIGCONT,dosig);
  276. sigsetmask(sigmask(SIGCONT));
  277. kill(0,SIGTSTP);
  278. while(!yep) sigpause(0);
  279. signal(SIGCONT,SIG_DFL);
  280. aopen();
  281. #else
  282. shell();
  283. #endif
  284. }
  285.